<!DOCTYPE html>
<html>
    <head>
        <title>对话框函数</title>
        <meta charset="utf-8">
        <style>
            .js-hide{display: none !important;}
            .dialog-mask{position: fixed;left: 0;right: 0;top: 0;bottom: 0;z-index: 9999;background: rgba(0,0,0,.3)}
            .dialog-con{width: 50%;max-height: 60%;padding: 20px;position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);background: #fff;}
            .dialog-close{position: absolute;right: 20px;top: 20px;}
        </style>
    </head>
    <body>
    <script>
    //定义一个函数  ，这个函数将 一个对象中不为undefined的元素赋给另一个对象，并返回另一个对象
        function mixin(target, op){
            for(var i in op){
                if(op[i] != undefined){
                    target[i] = op[i];
                }
            }
            return target;
        }
    //查看一个节点中是否含有classname
        function hasClass(el, className){
            if(el && el.className !== void 0){
                var classList = el.className.split(/\s+/);
                if(classList.indexOf(className) > -1){
                    return true;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }
        function removeClass(el, className){
            if(hasClass(el, className)){
                var classList = el.className.split(/\s+/);
                var deleteIndex = classList.indexOf(className);
                classList.splice(deleteIndex, 1);
                el.className = classList.join(' ');
            }
        }
        function addClass(el, className){
            if(!hasClass(el, className)){
                el.className = el.className + ' ' + className;
            }
        }
        function Dialog(params){
            if(!(this instanceof Dialog)){
                return new Dialog(params);
            }
            //这里的this指的是params  因为调用他的是params  
            //如果不存在，那么构造函数创建一个新的
            var defaultConfig = {
                maskClose: true,
                buttons: [{
                    name: '确定',
                    needClose: true,
                    needDestory: true,
                    callback: function(){
                        console.log(1);
                    }
                }],
                title: 'title',
                content: 'content',
                needClose: true,
                autoShow: true,
                hideDestory: true
            }
            //一个对象 ，default config缺省配置 分别是按钮  title   内容 是否需要关闭，是否自动展示，是否毁灭
            this.config = mixin(defaultConfig, params);
            // 如果有级尝试将params的每一个成员赋给缺省，如果没有 ，就相当于用默认的队形
            this.init();
            // 调用函数 ，据说是面向对象，本质是prototype
        }
        Dialog.prototype.init = function(){
            this.render();
            //调用函数
            if(this.config.needClose){
                this.$close = this.$el.getElementsByClassName('dialog-close')[0];
            }
            //当需要删除的flag为真，在dom中找到dialog-close
            this.bindEvent();
            if(this.config.autoShow){
                this.show();
            }
        }
        Dialog.prototype.bindEvent = function(){
            var me = this;
            if(me.$close){
                me.$close.addEventListener('click', function(e){
                    me.hide();
                })
            }
            //如果在dom流中有close这个节点，那么给他添加点击事件。点击事件是hide
            if((me.config.buttons && me.config.buttons.length) || me.config.maskClose){
                me.$el.addEventListener('click', function(e){
                    var target = e.target;
                    if(hasClass(target, 'dialog-btn')){
                        var index = target.getAttribute('data-index');
                        if(me.config.buttons[index] && me.config.buttons[index].needClose){
                            me.hide();
                        }
                        if(me.config.buttons[index] && me.config.buttons[index].needDestory){
                            me.destory();
                        }
                        if(me.config.buttons[index] && me.config.buttons[index].callback && (typeof me.config.buttons[index].callback == 'function')){
                            me.config.buttons[index].callback();
                        }
                    }

                    if(me.config.maskClose && hasClass(target, 'dialog-mask')){
                        me.hide();
                    }
                })
            }
        }
        Dialog.prototype.render = function(){
            this.$el = document.createElement('div');
            //创建一个div
            this.$el.className = 'js-hide';
            //给新建的div复制class为隐藏的，也就是说一开始应该是不显示的
            this.$el.innerHTML = this.getHTML();
            //在这个div中插入内容
            document.body.appendChild(this.$el);
            //帮这个div作为一个元素插入到body中
        }
        Dialog.prototype.getHTML = function(){
            return  '<div class="dialog-mask">' +
                        '<div class="dialog-con">' +
                            (this.config.needClose ? '<div class="dialog-close">x</div>' : '') +
                            '<div class="dialog-title">' + this.config.title + '</div>' + 
                            '<div class="dialog-content">' + this.config.content + '</div>' +
                            '<div class="dialog-btns">' + this.config.buttons.map(function(item, index){
                                return '<button class="dialog-btn" data-index="' + index + '">' + item.name + '</button>'
                            }).join('') + '</div>'
                        '</div>' +
                    '</div>'
        }
        Dialog.prototype.show = function(){
            if(this.$el){
                removeClass(this.$el, 'js-hide');
            }
        }
        Dialog.prototype.destory = function(){
            this.$el.remove();
        }
        //调用remove函数 移除被选中的元素，包括子节点和所有的文本，但是以后还可以调用
        Dialog.prototype.hide = function(){
            addClass(this.$el, 'js-hide');
            if(this.config.hideDestory){
                this.destory();
            }
        }
        //当hide函数发生时，添加隐藏到调用他的函数
        //如果hidedestory为真
        //那么调用destory函数

        // var d = Dialog();
        function Alert(msg){
            return Dialog({
                title: '',
                content: msg,
                buttons: [{
                    name: '确定',
                    needClose: true,
                    needDestory: true
                }]
            })
        }
        Alert('test');

    </script>
    </body>
</html>